<!--
Date: 2025-08-13
Copyright (c) 2025 Industrial Software Feature Database
-->
<template>
  <div class="parameterView" v-loading="loading">
    <div class="left">
      <el-tree
        :data="parameterTree"
        default-expand-all
        highlight-current
        node-key="index"
        @node-click="treeSelect"
      >
        <template #default="{ node, data }">
          <span class="custom-tree-node">
            <el-icon class="icon-class" v-if="data?.children?.length > 0"><Folder /></el-icon>
            <el-icon class="icon-class" v-else><Document /></el-icon>
            <span class="node-title">{{ node.label }}</span>
          </span>
        </template>
      </el-tree>
    </div>
    <div class="right">
      <div class="query_div">
        <el-form inline size="small" class="form_class" label-width="100">
          <el-form-item label="算子名" style="width: 100%">
            <el-select
              clearable
              style="width: 94%"
              v-model="queryParams.operatorName"
              filterable
              remote
              reserve-keyword
              placeholder="请输入算子名"
              :remote-method="remoteMethod"
              :loading="selectLoading"
            >
              <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.label" />
            </el-select>
          </el-form-item>
          <el-form-item label="path">
            <el-input v-model="queryParams.path" clearable />
          </el-form-item>
          <el-form-item label="type">
            <el-select v-model="queryParams.type" clearable>
              <el-option label="page" value="page"></el-option>
              <el-option label="parameter_field" value="parameter_field"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="component">
            <el-input v-model="queryParams.component" clearable />
          </el-form-item>
          <el-form-item label="label">
            <el-input v-model="queryParams.label" clearable />
          </el-form-item>
          <el-form-item label="field_id">
            <el-input v-model="queryParams.fieldId" clearable />
          </el-form-item>
          <el-form-item label="field_type">
            <el-select v-model="queryParams.fieldType" clearable>
              <el-option label="input" value="input"></el-option>
              <el-option label="select" value="select"></el-option>
              <el-option label="radio-group" value="radio-group"></el-option>
              <el-option label="table" value="table"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="value_type">
            <el-select v-model="queryParams.valueType" clearable>
              <el-option label="input" value="number"></el-option>
              <el-option label="select" value="text"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item style="margin-left: 100px">
            <el-button type="primary" size="small" @click="buttonClick('query')">查询</el-button>
            <el-button size="small" @click="buttonClick('reset')">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div class="btn_div">
        <el-button size="small" type="primary" @click="buttonClick('add')">
          <el-icon class="el-icon--left"><Plus /></el-icon>添加算子参数
        </el-button>
        <el-button size="small" type="primary" @click="buttonClick('import')">
          <el-icon class="el-icon--left"><UploadFilled /></el-icon>导入算子参数配置
        </el-button>
        <el-button size="small" type="primary" @click="buttonClick('download')">
          <el-icon class="el-icon--left"><CircleCheck /></el-icon>导出算子参数配置
        </el-button>
        <el-button size="small" type="primary" @click="buttonClick('downloadM')">
          <el-icon class="el-icon--left"><Download /></el-icon>下载参数定义模板
        </el-button>
      </div>
      <div class="table_div" v-loading="tableLoading">
        <el-table :data="tableData">
          <el-table-column
            v-for="item in columns"
            show-overflow-tooltip
            :fixed="item.prop === 'operatorName' ? 'left' : null"
            :key="item.label"
            :label="item.label"
            :prop="item.prop"
          />
          <el-table-column label="操作" width="180" fixed="right">
            <template #default="scope">
              <el-tooltip content="修改" placement="top">
                <el-button size="small" link type="primary" icon="EditPen" @click="buttonClick('edit', scope.row)">修改</el-button>
              </el-tooltip>
              <el-tooltip content="删除" placement="top">
                <el-button size="small" link type="primary" icon="Delete" @click="buttonClick('delete', scope.row)">删除</el-button>
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
        <div class="pagenation">
          <pagination
            v-show="total > 0"
            style="margin-top: 0;"
            v-model:page="queryParams.pageNum"
            v-model:limit="queryParams.pageSize"
            :total="total"
            :background="false"
            layout="total, sizes, prev, pager, next, jumper"
            @pagination="handleCurrentChange"
          />
        </div>
      </div>
    </div>
    <AddOperatorParameter
      v-if="addOperatorParameterVisible"
      :addOperatorParameterVisible="addOperatorParameterVisible"
      :rowData="currentData"
      @handleEvent="handleEvent"
    />
    <ImportData v-if="importVisible" :importVisible="importVisible" @handleImportEvent="handleImportEvent" />
  </div>
</template>
      
<script name="OperatorParameter" setup >
import { getOperatorPrameterList, deleteOperatorMapParameter, getOperatorTree, downloadTemplate, exportData } from '@/api/parameterLibrary';
import { getOperatorList } from '@/api/algorithmLibrary';

import AddOperatorParameter from './AddOperatorParameter.vue';
import ImportData from './ImportData.vue';

const parameterTree = ref([]);
const tableData = ref([]);
const currentData = ref(null);
const columns = [
  { label: '算子名', prop: 'operatorName', fixed: 'left' },
  { label: 'path', prop: 'path' },
  { label: 'type', prop: 'type' },
  { label: 'sort_order', prop: 'sortOrder' },
  { label: 'component', prop: 'component' },
  { label: 'label', prop: 'label' },
  { label: 'field_id', prop: 'fieldId' },
  { label: 'field_type', prop: 'fieldType' },
  { label: '自定义配置', prop: 'customJsonFieldObject' }
];
const queryParams = ref({
  pageNum: 1,
  pageSize: 10,
  path: '',
  type: '',
  sortOrder: '',
  component: '',
  label: '',
  fieldId: '',
  fieldType: '',
  valueType: ''
});
const total = ref(0);
const loading = ref(false);
const addOperatorParameterVisible = ref(false);
const currentNode = ref(null);
const options = ref([]);
const selectLoading = ref(false);
const tableLoading = ref(false);
const importVisible = ref(false);

const handleImportEvent = (data) => {
  importVisible.value = false;
  // if (data.type === 'submit') {
    queryDataByCondition();
  // }
};
//翻页
const handleCurrentChange = () => {
  queryDataByCondition();
};
//点击左侧树事件
const treeSelect = (selected) => {
  if (selected.children.length > 0) {
    return;
  } else {
    //设置form表单并执行查询
    queryParams.value.path = selected.fullPath;
    queryDataByCondition();
  }
};
//加载算子下拉选项
const remoteMethod = (query) => {
  if (query) {
    selectLoading.value = true;
    const params = {
      pageNum: 1,
      pageSize: 20,
      operatorName: query,
      algorithmRealize: '',
      caculate: '',
      type: '',
      isAsc: 'descending'
    };
    setTimeout(() => {
      getOperatorList(params)
        .then((res) => {
          if (res?.rows) {
            options.value = res?.rows.map((el) => {
              return { label: el.operatorName, value: el._id };
            });
          }
        })
        .finally(() => {
          selectLoading.value = false;
        });
    }, 200);
  } else {
    options.value = [];
  }
};
const buttonClick = (type, data) => {
  if (type === 'add') {
    currentData.value = null;
    addOperatorParameterVisible.value = true;
  }
  if (type === 'query') {
    queryDataByCondition();
  }
  if (type === 'reset') {
    queryParams.value = {
      pageNum: 1,
      pageSize: 10,
      path: '',
      type: '',
      sortOrder: '',
      component: '',
      label: '',
      fieldId: '',
      fieldType: '',
      valueType: ''
    };
    queryDataByCondition();
  }
  if (type === 'edit') {
    currentData.value = data;
    addOperatorParameterVisible.value = true;
  }
  if (type === 'delete') {
    doDelete(data);
  }
  if (type === 'downloadM') {
    downloadTemplate().then((res) => {
      const url = window.URL.createObjectURL(new Blob([res]));
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', 'operator_parameter_config.xlsx'); // 设定下载文件名
      document.body.appendChild(link);
      link.click();
      link.remove(); // 删除临时创建的链接
    });
  }
  if (type === 'download') {
    const params = { ...queryParams.value };
    delete params.pageNum;
    delete params.pageSize;
    exportData(params).then((res) => {
      const url = window.URL.createObjectURL(new Blob([res]));
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', 'operator_parameter_data.xlsx'); // 设定下载文件名
      document.body.appendChild(link);
      link.click();
      link.remove(); // 删除临时创建的链接
    });
  }
  if (type === 'import') {
    importVisible.value = true;
  }
};
// 删除
const doDelete = (data) => {
  ElMessageBox.confirm('是否确认删除该数据项？', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    deleteOperatorMapParameter(data._id).then((res) => {
      if (res) {
        ElMessage({ showClose: true, message: '删除成功', type: 'success' });
        queryDataByCondition();
      }
    });
  });
};
const handleEvent = (data) => {
  addOperatorParameterVisible.value = false;
  if (data.type === 'refresh') {
    currentData.value = null;
    queryDataByCondition();
  }
};
const getTree = () => {
  loading.value = true;
  getOperatorTree()
    .then(async (res) => {
      if (res) {
        await listToTree(res?.data?.children || []);
        loading.value = false;
        //设置form数据
        // setFormData();
        //查询第一个树节点数据
        queryDataByCondition();
      }
    })
    .finally(() => {
      loading.value = false;
    });
};
const setFormData = () => {
  if (currentNode.value) {
    queryParams.value.path = currentNode.value.fullPath;
  }
};
// 查询数据
const queryDataByCondition = () => {
  tableLoading.value = true;
  tableData.value = [];
  getOperatorPrameterList(queryParams.value)
    .then((res) => {
      if (res?.rows) {
        //处理自定义数据
        res.rows.forEach((el) => {
          el.customJsonFieldObject = JSON.stringify(el.customJsonFieldObject);
        });
        tableData.value = res.rows || [];
        total.value = res.total;
      }
    })
    .finally(() => {
      tableLoading.value = false;
    });
};
let index = 0;
const listToTree = (list) => {
  if (list.length !== 0) {
    list.forEach((el) => {
      index += 1;
      el.label = el.path;
      el.value = el.fullPath;
      el.index = index;
      if (index === 1) {
        currentNode.value = el;
      }
      if (el?.children.length > 0) {
        listToTree(el.children);
      }
    });
  }
  parameterTree.value = list;
};
onMounted(() => {
  getTree();
});
</script>
  <style scoped lang="scss">
.parameterView {
  display: flex;
  .left {
    width: 200px;
    overflow: auto;
    height: calc(100vh - 155px);
    .custom-tree-node {
      display: flex;
      .icon-class {
        color: rgba(193, 190, 190);
        font-size: 120%;
      }
      .node-title {
        padding-left: 5px;
      }
    }
  }
  .right {
    width: calc(100% - 200px);
    padding-left: 20px;
    height: calc(100vh - 155px);
    overflow-x: hidden;
    .form_class {
      border: 1px solid #dddddd7a;
      padding: 10px;
      margin-top: 10px;
      margin-bottom: 10px;
    }
    .btn_div {
      margin-bottom: 10px;
    }
    .table_div {
      .pagenation {
        display: flex;
        justify-content: end;
        margin-top: 10px;
      }
    }
  }
}

:deep(.el-cascader) {
  width: 100%;
}
</style>